package graphicalUserInterface;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;

import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wb.swt.SWTResourceManager;
import org.xml.sax.SAXException;

import settings.MasterController;

import entity.CashFlow;
import entity.Category;
import entity.Expense;
import entity.Source;
import entity.CashFlow.Period;
import exception.IllegalInput;
import exception.NullVariableFound;
import org.eclipse.swt.widgets.DateTime;
//@author U096819H
public class EditRemoveExpense extends Dialog {

	protected Object result;
	protected Shell shell;
	private Composite expense_composite;
	//@author U096819H
	public EditRemoveExpense(Shell parent, int style) {
		super(parent, style);
		setText("Edit Expense");
	}
	//@author U096819H
	public void open(Expense _ex, final MasterController mc)
			throws TransformerConfigurationException, InstantiationException,
			IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException {
		createContents(_ex, mc);
		shell.open();
		shell.layout();
		Display display = getParent().getDisplay();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}
	//@author U096819H
	private void createContents(Expense _ex, MasterController mc)
			throws TransformerConfigurationException, InstantiationException,
			IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException {
		shell = new Shell(getParent(), getStyle());
		shell.setSize(400, 275);
		shell.setText(getText());
		shell.setLayout(new FormLayout());

		expense_composite = new Composite(shell, SWT.NONE);
		expense_composite.setLayout(new GridLayout(4, false));
		FormData fd_expense_composite = new FormData();
		fd_expense_composite.top = new FormAttachment(0, 13);
		fd_expense_composite.bottom = new FormAttachment(100, 0);
		fd_expense_composite.left = new FormAttachment(0, 13);
		fd_expense_composite.right = new FormAttachment(0, 387);
		expense_composite.setLayoutData(fd_expense_composite);

		refreshExpenseForm(_ex, mc);

	}
	//@author U096819H
	public void refreshExpenseForm(final Expense _ex, final MasterController mc)
			throws TransformerConfigurationException, InstantiationException,
			IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException {

		// ---------::: EXPENSE :::---------
		// Title Input
		Label lblTitle = new Label(expense_composite, SWT.NONE);
		lblTitle.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
				false, 1, 1));
		lblTitle.setText("Title");

		final Text title_input = new Text(expense_composite, SWT.BORDER);
		title_input.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false, 3, 1));
		title_input.setText(_ex.getName());

		// Amount Input
		Label lblAmount = new Label(expense_composite, SWT.NONE);
		lblAmount.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
				false, 1, 1));
		lblAmount.setText("Amount");

		final Text amount_input = new Text(expense_composite, SWT.BORDER);
		amount_input.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false, 3, 1));
		amount_input.setText(String.valueOf(_ex.getAmount()));

		// Category Input
		Label lblCategory = new Label(expense_composite, SWT.NONE);
		lblCategory.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
				false, 1, 1));
		lblCategory.setText("Category");

		final Combo category_input = new Combo(expense_composite, SWT.READ_ONLY);
		category_input.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false, 3, 1));
		// TO DO: fill combo list with get all categoryTitle
		ArrayList<Category> catList = mc.GetAllCategory();
		String[] catNames = new String[catList.size()];
		int catSelect = 0;
		for (int i = 0; i < catList.size(); i++) {
			catNames[i] = catList.get(i).getName();
			if (catList.get(i).getName()
					.equalsIgnoreCase(_ex.getCategory().getName())) {
				catSelect = i;
			}
		}
		category_input.setItems(catNames);
		category_input.select(catSelect);

		// Source Input
		Label lblSource = new Label(expense_composite, SWT.NONE);
		lblSource.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
				false, 1, 1));
		lblSource.setText("Source");

		final Combo combo_2 = new Combo(expense_composite, SWT.READ_ONLY);
		combo_2.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
				3, 1));

		Label lblDate = new Label(expense_composite, SWT.NONE);
		lblDate.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false,
				1, 1));
		lblDate.setAlignment(SWT.RIGHT);
		lblDate.setText("Date");
		// TO DO: fill combo list with get all sourceTitle
		ArrayList<Source> sourceList = mc.GetAllSource();
		String[] sourceNames = new String[sourceList.size()];
		int srcSelect = 0;
		for (int i = 0; i < sourceList.size(); i++) {
			sourceNames[i] = sourceList.get(i).getName();
			if (sourceList.get(i).getName()
					.equalsIgnoreCase(_ex.getSource().getName())) {
				srcSelect = i;
			}
		}
		combo_2.setItems(sourceNames);
		combo_2.select(srcSelect);

		// Recursive Input
		final DateTime dateTime = new DateTime(expense_composite, SWT.BORDER
				| SWT.DROP_DOWN);
		new Label(expense_composite, SWT.NONE);
		new Label(expense_composite, SWT.NONE);
		new Label(expense_composite, SWT.NONE);
		dateTime.setDate(_ex.getDate().get(1), _ex.getDate().get(2), _ex.getDate().get(5));
		final Button btnRecursive = new Button(expense_composite, SWT.CHECK);
		final Combo combo_3 = new Combo(expense_composite, SWT.READ_ONLY);
		combo_3.setEnabled(_ex.getRecurs());
		final String[] recursiveOptions = { "Yearly", "Monthly", "Weekly",
				"Daily" };
		if (_ex.getRecurs()) {
			for (int i = 0; i < recursiveOptions.length; i++) {
				System.out.println(_ex.getRecursPeriod().toString());
				if (recursiveOptions[i].equalsIgnoreCase(_ex.getRecursPeriod()
						.toString())) {
					combo_3.select(i);
					break;
				}
			}
		}
		combo_3.setItems(recursiveOptions);
		combo_3.select(0);
		combo_3.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false,
				1, 1));
		btnRecursive.setSelection(_ex.getRecurs());
		btnRecursive.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (btnRecursive.getSelection()) {
					combo_3.setEnabled(true);
				} else {
					combo_3.setEnabled(false);
				}
			}
		});
		btnRecursive.setText("Recursive");
		new Label(expense_composite, SWT.NONE);
		new Label(expense_composite, SWT.NONE);
		new Label(expense_composite, SWT.NONE);
		Label lblPeriod = new Label(expense_composite, SWT.NONE);
		lblPeriod.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
				false, 1, 1));

		new Label(expense_composite, SWT.NONE);
		new Label(expense_composite, SWT.NONE);

		Button btnEmailToFriend = new Button(expense_composite, SWT.NONE);
		btnEmailToFriend.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				EmailView ev = new EmailView(expense_composite.getShell(), 65);
				SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
				String message = "\nTitle: " + _ex.getName() + "\nAmount: "
						+ String.valueOf(_ex.getAmount()) + "\nCategory: "
						+ _ex.getCategory().getName() + "\nSource: "
						+ _ex.getSource().getName() + "\nDate: "
						+ dateFormat.format(_ex.getDate().getTime())
						+ "\nRecurring: " + String.valueOf(_ex.getRecurs());
				if (_ex.getRecurs()) {
					message = message + "\nRecurring Period: "
							+ _ex.getRecursPeriod().toString();
				}
				ev.open(message, "Expense");
			}
		});
		btnEmailToFriend.setText("Email to Friend");
		// End of Form

		Button btnSubmit = new Button(expense_composite, SWT.NONE);
		btnSubmit.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				// update expense
				ConfirmPrompt cnp = new ConfirmPrompt(expense_composite
						.getShell(), 65);
				if (cnp.open("Do you want to update expense?")) {
					try {
						Period recursP;
						if (btnRecursive.getSelection()) {
							recursP = CashFlow.Period.valueOf(recursiveOptions[combo_3
									.getSelectionIndex()].toUpperCase());
						} else {
							recursP = null;
						}
						// Date Check
						Calendar _date = Calendar.getInstance();
						_date.set(dateTime.getYear(), dateTime.getMonth(),
								dateTime.getDay());
						if (_date.before(Calendar.getInstance()) || _date.equals(Calendar.getInstance())) {
							try {
								mc.UpdateExpense(_ex.getId(), title_input
										.getText(), category_input
										.getItem(category_input
												.getSelectionIndex()), Double
										.parseDouble(amount_input.getText()),
										combo_2.getItem(combo_2
												.getSelectionIndex()), _date,
										btnRecursive.getSelection(), recursP,
										"");
								NotifyPrompt ntp = new NotifyPrompt(
										expense_composite.getShell(), 65);
								ntp.open("Expense updated.");
								shell.close();
							} catch (NumberFormatException | IllegalInput e1) {
								NotifyPrompt ntp = new NotifyPrompt(
										expense_composite.getShell(), 65);
								ntp.open("Error in updating expense.");
							}
						} else {
							NotifyPrompt ntp = new NotifyPrompt(
									expense_composite.getShell(), 65);
							ntp.open("Invalid date.");
						}
					} catch (NullVariableFound e1) {
						NotifyPrompt ntp = new NotifyPrompt(expense_composite
								.getShell(), 65);
						ntp.open("Error in updating expense.");
						e1.printStackTrace();
					} catch (InstantiationException | IllegalAccessException
							| JAXBException | ParserConfigurationException
							| SAXException | IOException | TransformerException e1) {
						// TODO Auto-generated catch block
						NotifyPrompt ntp = new NotifyPrompt(expense_composite
								.getShell(), 65);
						ntp.open("Error in updating expense.");
						e1.printStackTrace();
					}
				}
			}
		});
		GridData gd_btnSubmit = new GridData(SWT.RIGHT, SWT.CENTER, true,
				false, 1, 1);
		gd_btnSubmit.widthHint = 85;
		btnSubmit.setLayoutData(gd_btnSubmit);
		btnSubmit.setText("Update");

		Button btnDelete = new Button(expense_composite, SWT.NONE);

		btnDelete.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				ConfirmPrompt cnp = new ConfirmPrompt(expense_composite
						.getShell(), 65);
				if (cnp.open("Do you want to delete expense?")) {
					// delete expense
					try {
						try {
							mc.RemoveExpense(_ex.getId());
							NotifyPrompt ntp = new NotifyPrompt(
									expense_composite.getShell(), 65);
							ntp.open("Expense deleted.");
							shell.close();
						} catch (NullVariableFound e1) {
							// TODO Auto-generated catch block
							NotifyPrompt ntp = new NotifyPrompt(
									expense_composite.getShell(), 65);
							ntp.open("Error in deleting expense.");
							e1.printStackTrace();
						}
					} catch (InstantiationException | IllegalAccessException
							| JAXBException | ParserConfigurationException
							| SAXException | IOException | TransformerException e1) {
						// TODO Auto-generated catch block
						NotifyPrompt ntp = new NotifyPrompt(expense_composite
								.getShell(), 65);
						ntp.open("Error in deleting expense.");
						e1.printStackTrace();
					}
				}
			}
		});
		GridData gd_btnDelete = new GridData(SWT.RIGHT, SWT.CENTER, true,
				false, 1, 1);
		gd_btnDelete.widthHint = 85;
		btnDelete.setLayoutData(gd_btnDelete);
		btnDelete.setText("Delete");
	}
}
